// Start Rekit Studio
const path = require('path')
const http = require('http')
const bodyParser = require('body-parser')
const express = require('express')
const fallback = require('express-history-api-fallback')
const ejs = require('ejs')
const fs = require('fs')

const deleteFolder = (path) => {
  var files = []
  if (fs.existsSync(path)) {
    if (path.indexOf('.tsx') === -1 && path.indexOf('.scss') === -1) {
      files = fs.readdirSync(path)
      files.forEach(function (file, index) {
        const u = path + '/' + file
        if (fs.statSync(u).isDirectory()) {
          // recurse
          deleteFolder(u)
        } else {
          // delete file
          fs.unlinkSync(u)
        }
      })
      fs.rmdirSync(path)
    } else {
      fs.unlinkSync(path)
    }
  }
}

const success = (data) => {
  return {
    code: 1,
    status: 'done',
    data: data || null,
  }
}
const handleUrl = (url) => {
  const uIndex = url.indexOf('/src')
  return '..' + url.substring(uIndex)
}
const createComponent = (
  name,
  p,
  str,
  styleStr,
  modelStr,
  res,
  next,
  style,
  model,
) => {
  const u = path.join(__dirname, p)
  const models = path.join(__dirname, '../src/models')
  fs.mkdir(`${u}/${name}`, (error) => {
    if (error) {
      next(error)
      return
    } else {
      console.log('创建目录成功')
      fs.writeFile(`${u}/${name}/index.tsx`, str, 'utf8', (error) => {
        if (error) {
          next(error)
          return
        }
        console.log('写入组件')
      })
      if (style) {
        fs.writeFile(`${u}/${name}/index.scss`, styleStr, 'utf8', (error) => {
          if (error) {
            next(error)
            return
          }
          console.log('写入样式')
        })
      }
      if (model) {
        fs.writeFile(`${models}/${name}.ts`, modelStr, 'utf8', (error) => {
          if (error) {
            next(error)
            return
          }
          console.log('写入model')
        })
        console.log(fs.readdirSync(models))
      }
    }
  })
}

const toLowerLine = (str) => {
  var temp = str.replace(/[A-Z]/g, function (match) {
    return '-' + match.toLowerCase()
  })
  if (temp.slice(0, 1) === '-') {
    //如果首字母是大写，执行replace时会多一个-，这里需要去掉
    temp = temp.slice(1)
  }
  return temp
}

function startRekitStudio() {
  let port = 3001
  console.log('Starting Rekit Studio...')
  return new Promise((resolve, reject) => {
    const app = express()
    const server = http.createServer(app)
    console.log(path.join(__dirname, '../config/dist'))
    const root = path.join(__dirname, '../config/dist')
    app.use(express.static(root))
    app.use(fallback('index.html', { root }))
    app.use(bodyParser.json({ limit: '5MB' }))
    app.use(bodyParser.urlencoded({ extended: true }))
    app.post('/skyApi/addComponent', (req, res, next) => {
      const { name, model, p, componentType, style } = req.body
      const styleName = toLowerLine(name)
      const cTp = {
        1: 'Component',
        2: 'HooksComponent',
        3: 'TableComponent',
      }
      const componentStr = ejs.render(
        fs.readFileSync(
          path.join(__dirname, `../config/template/${cTp[componentType]}.ejs`),
          'utf-8',
        ),
        { name, styleName, model, style },
      )
      const styleStr = ejs.render(
        fs.readFileSync(
          path.join(__dirname, '../config/template/Style.ejs'),
          'utf-8',
        ),
        { name, styleName },
      )
      const modelStr = ejs.render(
        fs.readFileSync(
          path.join(__dirname, '../config/template/Model.ejs'),
          'utf-8',
        ),
        { name },
      )
      createComponent(
        name,
        p,
        componentStr,
        styleStr,
        modelStr,
        res,
        next,
        style,
        model,
      )
      res.send(success())
      resolve()
    })
    app.post('/skyApi/getFiles', (req, res, next) => {
      //递归取出当前src下的列表
      const deepFileJson = (p, i) => {
        let components = []
        const files = fs.readdirSync(p)
        files.forEach(function (item, index) {
          const pchild = p + '/' + item
          let stat = fs.lstatSync(pchild)
          if (stat.isDirectory() === true) {
            const filesChildren = fs.readdirSync(pchild)
            const isFile = filesChildren.some(
              (item) =>
                fs.lstatSync(pchild + '/' + item).isDirectory() === true,
            )
            components.push({
              name: item,
              type: 1,
              path: handleUrl(pchild),
              children: isFile
                ? deepFileJson(pchild)
                : filesChildren.map((o) => {
                    const opchild = pchild + '/' + o
                    let ostat = fs.lstatSync(opchild)
                    if (ostat.isDirectory() === false) {
                      return {
                        name: o,
                        type: 0,
                        path: handleUrl(opchild),
                      }
                    }
                  }),
            })
          } else {
            components.push({
              name: item,
              type: 0,
              path: handleUrl(pchild),
            })
          }
        })
        return components
      }
      const components = deepFileJson(path.join(__dirname, '../src/pages'))
      const callbackArray = [
        {
          children: [...components],
          name: 'Features',
          type: 1,
          path: '../src/pages',
        },
      ]
      res.send(success(callbackArray))
    })
    app.post('/skyApi/delete', (req, res, next) => {
      const url = path.join(__dirname, req.body.item.path)
      deleteFolder(url)
      res.send(success())
    })
    server.listen(port, (error) => {
      app.use((err, req, res, next) => {
        res.status(500).send({ error: err.message })
      })
      console.log(`Sky Rekit Studio is running at http://localhost:${port}/`)
    })
  })
}
startRekitStudio()
// module.exports = startRekitStudio
